package com.xb.loan.fund.impl;
import com.xb.loan.account.service.ICashService;
import com.xb.loan.account.service.constant.AccountConst;
import com.xb.loan.account.service.exception.IAccountServiceException;
import com.xb.loan.encryptor.crypt.Encryptor;
import com.xb.loan.encryptor.crypt.EncryptorManager;
import com.xb.loan.fund.common.VerifySet;
import com.xb.loan.fund.dao.CashEncashDao;
import com.xb.loan.fund.dao.bean.CashEncash;
import com.xb.loan.fund.dao.bean.CashEncashRec;
import com.xb.loan.fund.service.ICashEncashService;
import com.xb.loan.fund.service.ICashVerifyErrorService;
import com.xb.loan.fund.service.bean.CashEncashRecVO;
import com.xb.loan.fund.service.bean.CashEncashVO;
import com.xb.loan.fund.service.bean.CashVerifyErrorVO;
import com.xb.loan.fund.service.bean.EncashResultVO;
import com.xb.loan.fund.service.constant.FundConst;
import com.xb.loan.fund.service.exception.IFundServiceException;
import com.xb.loan.log.constant.IenumConstants;
import com.xb.loan.log.exception.BizException;
import com.xb.loan.usercenter.service.user.IUserBankCardService;
import com.xb.loan.usercenter.service.user.IUserService;
import com.xb.loan.usercenter.service.user.IUserThresholdService;
import com.xb.loan.usercenter.service.user.bean.UserBankCardVO;
import com.xb.loan.usercenter.service.user.bean.UserInfoVO;
import com.xb.loan.usercenter.service.user.bean.UserThresholdVO;
import com.xb.loan.usercenter.service.user.exception.IUserServiceException;
import com.xb.loan.util.DateHelper;
import com.xb.loan.util.cache.redis.comm.FormatOperation;
import com.xb.loan.util.common.ObjectOperation;
import com.xb.loan.util.log.DefaultLoggerFacotry;
import com.xb.loan.util.log.LogFormatUtil;
import com.xb.loan.util.mybatis.MyTransactional;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 北京掌中彩信息科技有限公司源代码，版权归北京掌中彩信息科技有限公司所有。
 * 
 * 项目名称 : common-biz 创建日期 : 2015年9月7日 类 描 述 : 提现逻辑操作 修改历史 : 1. [2015年9月7日]创建文件
 * wuqinglong
 */
@Service("cashEncashService")
public class CashEncashServiceImpl implements ICashEncashService, IFundServiceException, IUserServiceException,
		IAccountServiceException {

	private static Logger logger = DefaultLoggerFacotry.getLogger(CashEncashServiceImpl.class);
	
	@Autowired
	private IUserService userService;

	@Autowired
	private ICashService cashService;

	@Autowired
	private IUserThresholdService userThresholdService;
	
	@Autowired
	private IUserBankCardService payCardService;

	@Autowired
	private CashEncashDao cashEncashDao;

    @Autowired
    private IPartnerInfoService partnerInfoService;
    
	@Autowired
	private ICashVerifyErrorService verifyErrorService;
	
	// 加密算法（用于与收银台通讯）
	Encryptor partnerEncrytor = EncryptorManager.getEncryptor("partner");
	// 加密算法（用于本地防篡改）
	Encryptor userEncrytor = EncryptorManager.getEncryptor("user");

	@Autowired
	// ① 注入上下文
	private ApplicationContext context;

	private CashEncashServiceImpl proxySelf; // ② 表示代理对象，不是目标对象

	@PostConstruct
	// ③ 初始化方法
	private void setSelf() {
		// 从上下文获取代理对象（如果通过proxtSelf=this是不对的，this是目标对象）
		// 此种方法不适合于prototype Bean，因为每次getBean返回一个新的Bean
		proxySelf = (CashEncashServiceImpl) context.getBean(ICashEncashService.class);
	}
	
	@Override
	public CashEncashVO encash(CashEncashVO cashEncashVO) throws BizException {
		verifyEncash(cashEncashVO);
		UserInfoVO userInfoVO = userService.queryUserInfoById(cashEncashVO.getUserId());
		VerifySet.verifyUserInfoVOIsNormal(userInfoVO);
		
		// 生成提现订单ID
		String encashId = FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length);
		cashEncashVO.setEncashId(encashId);
		if(StringUtils.isEmpty(cashEncashVO.getPid())){// 手机端没有porder_id字段
			cashEncashVO.setPid(encashId);
		}
		
		// 验证是否是重复订单
		verifyRepeatOrder(cashEncashVO.getPartnerId(), cashEncashVO.getPid());
		
		// 彩民受限于资金审核
		if(userInfoVO.getUserLevel() != IenumConstants.UserLevel.CHANNEL.getCode()){
			UserThresholdVO userThresholdVO = userThresholdService.queryByPartnerId(cashEncashVO.getPartnerId());
			// 验证提现阈值
			verifyThreshold(userThresholdVO, cashEncashVO);
			
			double money = cashEncashVO.getMoney();
			// 通过金额判断该提现订单是否要审核，常量通过配置文件读取
			if (money >= userThresholdVO.getEncashThreshold()) {//上线的时候，要回滚
				cashEncashVO.setStatus(FundConst.EncashStatus_WaitApprove);
			} else {
				cashEncashVO.setStatus(FundConst.EncashStatus_Wait);
			}
		}else{
			cashEncashVO.setStatus(FundConst.EncashStatus_Wait);
		}
		
		cashEncashVO.setUserLevel(userInfoVO.getUserLevel());
		// 设置渠道的支付渠道集合
		PartnerInfoVO partnerInfoVO = partnerInfoService.selectByPrimaryKey(cashEncashVO.getPartnerId());
		if(StringUtils.isEmpty(partnerInfoVO.getCashierPlatId())){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "partnerId", "msg"},
					new Object[]{"encash", cashEncashVO.getPartnerId(), IPartnerServiceException.encashIsNotSupported.getMessage()}));
			throw IPartnerServiceException.encashIsNotSupported;
		}
		cashEncashVO.setPlatId(partnerInfoVO.getCashierPlatId());
		
		// 设置提现的银行卡
		setPayCard(cashEncashVO);
		
		// 设置账期
		Date now = new Date();
		cashEncashVO.setCreateTime(FormatOperation.formatDateToYMDHms14(now));
		cashEncashVO.setAccountPeriod(FormatOperation.formatDateToYMD(now));
		cashEncashVO.setAccountId(userInfoVO.getAccountId());
		cashEncashVO.setProcessTime(now);
		// 生成数字签名
		// 顺序：sign签名字段：money、platId、userId、orderId、partnerId、sell_name、sell_account
		String encryptStr = cashEncashVO.generateKey();
		// 使用“user模式”生成签名信息，防止本地篡改
		String digitalSign = userEncrytor.encrypt(cashEncashVO.getUserId(), encashId, encryptStr);
		cashEncashVO.setDigitalSign(digitalSign);
		cashEncashVO.setAccountStatus(FundConst.CheckAccountStatus_Wait);
		cashEncashVO.setUserType(userInfoVO.getUserType());
		// 提现记录插入和提现扣款
		proxySelf.encashTransaction(cashEncashVO, userInfoVO);
		return cashEncashVO;
	}
	
	private void verifyRepeatOrder(String partnerId, String pid) throws BizException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("partnerId", partnerId);
		map.put("pid", pid);
		CashEncash cashEncash = cashEncashDao.queryCashEncashByPid(map);
		if (cashEncash != null) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "partnerId", "pid", "msg"},
					new Object[] { "encash", partnerId, pid,
					IFundServiceException.RepeatOrder.getMessage()}));
			throw IFundServiceException.RepeatOrder;
		}
	}

	private void setPayCard(CashEncashVO cashEncashVO) throws BizException {
		if(StringUtils.isNotEmpty(cashEncashVO.getCardNo())){
			return;
		}
		// 提现用户未指定银行卡，使用默认银行卡
		String userId = cashEncashVO.getUserId();
		// 设置默认支付卡信息
		UserBankCardVO bankCardVO = payCardService.queryDefaultUserBankCard(userId);
		if(bankCardVO == null){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
					new String[]{"CashEncash.encash4Partner", IPartnerServiceException.partnerHasntPaycard.getMessage()}));
			throw IPartnerServiceException.partnerHasntPaycard;
		}
		cashEncashVO.setBankCode(bankCardVO.getBankCode());
		cashEncashVO.setBankName(bankCardVO.getBankName());
		cashEncashVO.setCardName(bankCardVO.getCardUsername());
		cashEncashVO.setCardNo(bankCardVO.getCardNo());
	}

	/**
	 * 验证提现阈值
	 * @param userThresholdVO 阈值记录
	 * @param list 提现记录集合
	 * @param money 提现金额 2015年9月14日 by wuqinglong
	 */
	private void verifyThreshold(UserThresholdVO userThresholdVO, CashEncashVO cashEncashVO)
			throws BizException {
		if(userThresholdVO == null){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "partnerId", "msg"},
					new Object[]{"encash", cashEncashVO.getPartnerId(),
					IFundServiceException.userThresholdNotExist.getMessage()}));
			throw IFundServiceException.userThresholdNotExist;
		}
		// 单笔最大金额限制
		if (cashEncashVO.getMoney() > userThresholdVO.getMaxEncashMoney()) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "userId", "money", "msg"},
					new Object[]{"encash", cashEncashVO.getUserId(), cashEncashVO.getMoney(),
					IFundServiceException.ViolateMaxMoneyLimit.getMessage()}));
			throw IFundServiceException.ViolateMaxMoneyLimit;
		}
		Date now = new Date();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userId", cashEncashVO.getUserId());
		params.put("startDate", DateHelper.getTodayStartTime(now));
		params.put("endDate", DateHelper.getTodayEndTime(now));
		int count = cashEncashDao.queryCashEncashCount(params);
		// 最大提现次数限制
		if(count >= userThresholdVO.getMaxEncashNum()){
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "userId", "sumOptNumToday", "msg"},
					new Object[]{"encash", cashEncashVO.getUserId(), count,
					IFundServiceException.ViolateSumOptNumLimit.getMessage()}));
			throw IFundServiceException.ViolateSumOptNumLimit;
		}
	}

	@MyTransactional
	public void encashTransaction(CashEncashVO cashEncashVO, UserInfoVO userInfoVO) throws BizException {
		// 提现扣款
		cashService.deductMoney(cashEncashVO.getEncashId(), userInfoVO, cashEncashVO.getMoney(),
				AccountConst.BillType_Encash, cashEncashVO.getAccountPeriod());
		CashEncash cashEncash = (CashEncash) ObjectOperation.convertByClasses(cashEncashVO, CashEncash.class);
		
		cashEncashDao.insert(cashEncash);
		// 分开部署，进行冲正
//		try{
//			cashEncashDao.insert(cashEncash);
//		}catch(Exception e){
//			cashService.flushes(userInfoVO.getUserId(), cashEncashVO.getEncashId(), AccountConst.BillType_Encash);
//		}
	}

	public void encashApprove(String encashId, int approveState, String approveDesc) throws BizException {
		if (encashId == null || (approveState != FundConst.Approve_Success && approveState != FundConst.Approve_Fail)) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "msg"},
					new Object[]{"CashEncash.encashApprove", inputParameterIsWrong.getMessage()}));
			throw inputParameterIsWrong;
		}
		// 不存在的提现订单
		CashEncash cashEncash = cashEncashDao.queryCashEncashById(encashId);
		if (cashEncash == null) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "encashId", "msg"},
					new Object[]{"CashEncash.encashApprove", encashId, IFundServiceException.encashNotExist.getMessage()}));
			throw IFundServiceException.encashNotExist;
		}
		String userId = cashEncash.getUserId();
		UserInfoVO userInfoVO = userService.queryUserInfoById(userId);
		// 登录名和渠道查询用户对象为空提示用户不存在
		if (userInfoVO == null) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "userId", "msg"},
					new Object[]{"CashEncash.encashApprove", userId, userInfoMissing.getMessage()}));
			throw userInfoMissing;
		}

		// 审核通过，修改提现记录状态为待处理 
		if (FundConst.Approve_Success == approveState) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("status", FundConst.EncashStatus_Wait);
			map.put("encashId", cashEncash.getEncashId());
			map.put("statusReason", approveDesc);
			map.put("processTime", true);
			cashEncashDao.updateCashEncash(map);
		} else {// 审核不通过，修改提现记录状态为审核失败，并退款
			proxySelf.encashApproveFailTransaction(cashEncash, userInfoVO, approveDesc);
		}
	}

	@MyTransactional
	public void encashApproveFailTransaction(CashEncash cashEncash, UserInfoVO userInfoVO, String statusReason) throws BizException {
		// 提现加钱
		cashService.addMoney(cashEncash.getEncashId(), userInfoVO, cashEncash.getMoney(),
				AccountConst.BillType_Encash_Refund, cashEncash.getAccountPeriod());

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("status", FundConst.EncashStatus_ApproveFail);
		map.put("statusReason", statusReason);
		map.put("encashId", cashEncash.getEncashId());
		map.put("processTime", true);
		cashEncashDao.updateCashEncash(map);
	}

	// 提现验证
	private void verifyEncash(CashEncashVO cashEncashVO) throws BizException {
		if (cashEncashVO == null || cashEncashVO.getUserId() == null) {
			// 参数错误
			logger.warn(inputParameterIsWrong.getMessage(), inputParameterIsWrong);
			// 抛出异常
			throw inputParameterIsWrong;
		}

	}

	@Override
	public void encashResult(EncashResultVO encashResultVO) throws BizException {
		// 1、提现订单是否存在
		CashEncash cashEncash = cashEncashDao.queryCashEncashById(encashResultVO.getEncashId());
		if (cashEncash == null) {
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "encashId", "msg"},
					new Object[]{"encash.encashResult", encashResultVO.getEncashId(), IFundServiceException.encashNotExist.getMessage()}));
			throw IFundServiceException.encashNotExist;
		}
		// 2、数据验签
		verifyEncashResult(encashResultVO, cashEncash);
		
		encashResultInner(cashEncash, encashResultVO.generateResult());
	}

	/**
	 * 提现结果操作
	 * @param cashEncash
	 * @param status 收银台通知结果
	 * 2016年1月28日 by wenju.song 
	 * @throws BizException 
	 */
	public void encashResultInner(CashEncash cashEncash, int status) throws BizException {
		// 1、提现订单已失败。
		if (cashEncash.getStatus() == FundConst.EncashStatus_Fail) {
			logger.info(LogFormatUtil.getFormatMsg(new String[] { "module", "encashId", "encash.status"},
					new Object[]{"encash.encashResult", cashEncash.getEncashId(), cashEncash.getStatus()}));
			return;
		}
		// 2、不是退票情况（第一次通知成功，第二次通知失败）
		if(cashEncash.getStatus() == FundConst.EncashStatus_Success && status == FundConst.EncashStatus_Success){
			logger.info(LogFormatUtil.getFormatMsg(new String[] { "module", "encashId", "encash.status", "encashResult.status"},
					new Object[]{"encash.encashResult", cashEncash.getEncashId(), cashEncash.getStatus(), status}));
			return;
		}
		
		UserInfoVO userInfoVO = userService.queryUserInfoById(cashEncash.getUserId());

		if (status == CashierResultStatus.SUCCESS.getCode()) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("encashId", cashEncash.getEncashId());
			map.put("status", FundConst.EncashStatus_Success);
			map.put("processTime", true);
			cashEncashDao.updateCashEncash(map);
		} else {
			proxySelf.encashResultFailTransaction(cashEncash, userInfoVO);
		}
	}

	/**
	 * 提现结果返回失败处理逻辑 失败操作：1)调用加钱接口把提现所扣款加上 2)修改提现记录状态
	 * @param cashEncash 提现记录
	 * @param userInfoVO 提现用户VO记录
	 * @throws BizException 2015年9月8日 by wuqinglong
	 */
	public void encashResultFailTransaction(CashEncash cashEncash, UserInfoVO userInfoVO) throws BizException {
		// 加钱，记入账
		cashService.addMoney(cashEncash.getEncashId(), userInfoVO, cashEncash.getMoney(),
				AccountConst.BillType_Encash_Refund, cashEncash.getAccountPeriod());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("encashId", cashEncash.getEncashId());
		map.put("status", FundConst.EncashStatus_Fail);
		map.put("processTime", true);
		cashEncashDao.updateCashEncash(map);
	}

	private void verifyEncashResult(EncashResultVO encashResultVO, CashEncash cashEncash) throws BizException {
		if (encashResultVO.getDigitalSign() == null || "".equals(encashResultVO.getDigitalSign())
				|| encashResultVO.getMoney() <= 0 || encashResultVO.getEncashId() == null
				|| "".equals(encashResultVO.getEncashId()) || encashResultVO.getPlatId() == null
				|| "".equals(encashResultVO.getPlatId()) || encashResultVO.getUserId() == null
				|| "".equals(encashResultVO.getUserId()) || encashResultVO.getPartnerId() == null
				|| "".equals(encashResultVO.getPartnerId()) || encashResultVO.getReturnCode() == null
				|| "".equals(encashResultVO.getReturnCode())) {
			logger.warn(inputParameterIsWrong.getMessage(), inputParameterIsWrong);
			// 抛出异常
			throw inputParameterIsWrong;
		}

		// 验证通过之后 验证本地的数据 根据订单Id查询本地的交易数据 对比信息是否一致
		if (cashEncash == null || cashEncash.getEncashId() == null || "".equals(cashEncash.getEncashId())) {
			// 报错 该订单不存在
			logger.warn(LogFormatUtil.getFormatMsg(new String[]{"module", "encashId", "msg"},
					new Object[]{"encash", encashResultVO.getEncashId(), IFundServiceException.encashNotExist.getMessage()}));
			throw IFundServiceException.encashNotExist;
		}

		// 解密签名(收银台的公钥) --》 对比结果 收银台数据是否被篡改
		String encryptStr = encashResultVO.generateKey();
		if (!partnerEncrytor.encryptValidate(FundConst.Cashier_Cert, null, encryptStr, encashResultVO.getDigitalSign())) {// 收银台 验签失败
			logger.warn(LogFormatUtil.getFormatMsg(new String[] { "module", "encashId", "userId", "money", "msg"},
					new Object[]{"encash", encashResultVO.getEncashId(), encashResultVO.getUserId(), encashResultVO.getMoney(),
					cashierDataIsBeDistort.getMessage()}));
			CashVerifyErrorVO verifyError = addVerifyError(encashResultVO, cashEncash,
					FundConst.VerifyErrorType_LOCALERROR);
			verifyErrorService.addCashVerifyError(verifyError);
			throw cashierDataIsBeDistort;
		}

		// 本地数据重新加密（平台的私钥） 验证本地数据是否被篡改了
		CashEncashVO cashEncashVO = (CashEncashVO) ObjectOperation.convertByClasses(cashEncash, CashEncashVO.class);

		// 本地数据没有篡改，则验证本地的数据与收银台返回的时候是否一致 (充值平台ID 充值用户ID 渠道ID 充值金额)要保持一致
		if (!cashEncashVO.getPlatId().equals(encashResultVO.getPlatId())
				|| !cashEncashVO.getUserId().equals(encashResultVO.getUserId())
				|| !cashEncashVO.getPartnerId().equals(encashResultVO.getPartnerId())
				|| cashEncashVO.getMoney() != encashResultVO.getMoney()) {
			
			logger.info(LogFormatUtil.getFormatMsg(new String[] {"module", "encashId", "msg"},
					new Object[]{"encash", encashResultVO.getEncashId(), TheLocalDataAndTransactionDataAreDifferent.getMessage()}));
			
			CashVerifyErrorVO verifyError = addVerifyError(encashResultVO, cashEncash, FundConst.VerifyErrorType_DATADIFFER);
			verifyErrorService.addCashVerifyError(verifyError);
			throw TheLocalDataAndTransactionDataAreDifferent;
		}

	}

	/**
	 * 生成错误日志
	 * @param encashResultVO 收银台返回
	 * @param cashEncash
	 * @param errorType
	 * @return
	 * @throws BizException 2015年9月15日 by wuqinglong
	 */
	private CashVerifyErrorVO addVerifyError(EncashResultVO encashResultVO, CashEncash cashEncash, Integer errorType)
			throws BizException {
		CashVerifyErrorVO cashVerifyErrorVO = new CashVerifyErrorVO();
		String fundLimitId = FormatOperation.assemblySeq(FundConst.PriKey_Name, FundConst.PriKey_Length);
		cashVerifyErrorVO.setFundLimitId(fundLimitId);
		if (cashEncash != null) {
			cashVerifyErrorVO.setUserId(cashEncash.getUserId());
			cashVerifyErrorVO.setPlatId(cashEncash.getPlatId());
			cashVerifyErrorVO.setPartnerId(cashEncash.getPartnerId());
			cashVerifyErrorVO.setMoney(cashEncash.getMoney());
			cashVerifyErrorVO.setAccountName(cashEncash.getCardName());
			cashVerifyErrorVO.setAccountNo(cashEncash.getCardNo());
			cashVerifyErrorVO.setDigitalSign(cashEncash.getDigitalSign());
			cashVerifyErrorVO.setOrderId(cashEncash.getEncashId());
		}
		if (encashResultVO != null) {
			cashVerifyErrorVO.setCashierUserId(encashResultVO.getUserId());
			cashVerifyErrorVO.setCashierPlatId(encashResultVO.getPlatId());
			cashVerifyErrorVO.setCashierPartnerId(encashResultVO.getPartnerId());
			cashVerifyErrorVO.setCashierMoney(encashResultVO.getMoney());
			cashVerifyErrorVO.setCashierOrderId(encashResultVO.getEncashId());
			cashVerifyErrorVO.setCashierReturnCode(encashResultVO.generateResult());
			cashVerifyErrorVO.setCashierDigitalSign(encashResultVO.getDigitalSign());
		}
		cashVerifyErrorVO.setErrorType(errorType);
		cashVerifyErrorVO.setOrderType(FundConst.FundType_Encash);
		cashVerifyErrorVO.setStatus(FundConst.VerifyErrorStatus_Wait);
		return cashVerifyErrorVO;
	}

	public int submitCashEncash(String encashId) throws BizException{
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("encashId", encashId);
        params.put("status", FundConst.EncashStatus_Handling);
        params.put("submitTime", new Date());
        return cashEncashDao.updateCashEncash(params);
    }
	
	public int updateAccountStatus(String encashId, int accountStatus) throws BizException{
	    Map<String, Object> params = new HashMap<String, Object>();
        params.put("encashId", encashId);
        params.put("accountStatus", accountStatus);
        return cashEncashDao.updateCashEncash(params);
	}
	
	public void clearAccountStatus(String accountPeriod){
	    cashEncashDao.clearAccountStatus(accountPeriod);
	}

    @Override
    public List<Map<String, Object>> statEncashDay(Map<String, Object> params) {
        return cashEncashDao.statEncashDay(params);
    }

	@Override
	public List<CashEncashVO> queryCashEncash(String userId, String partnerId,
                                              Integer status, String startDate, String endDate, int pageNum, int numPerPage) throws BizException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userId);
		map.put("partnerId", partnerId);
		map.put("status", status);
		map.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
        map.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));
		map.put("pageNum", pageNum);
		map.put("numPerPage", numPerPage);
		List<CashEncash> list = cashEncashDao.queryCashEncash(map);
		if (list != null ) {
		    for(CashEncash cashEncash : list)
		        cashEncash.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashEncash.getCreateTime()));
		}
		return ObjectOperation.convertByClassesList(list, CashEncashVO.class);
	}

	@Override
	public int queryCashEncashCount(String userId, String partnerId, Integer status,
                                    String startDate, String endDate) throws BizException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userId);
		map.put("partnerId", partnerId);
		map.put("status", status);
		map.put("startDate", FormatOperation.formatY_M_DHmsToYMDHms14(startDate));
        map.put("endDate", FormatOperation.formatY_M_DHmsToYMDHms14(endDate));
		return cashEncashDao.queryCashEncashCount(map);
	}

	@Override
	public CashEncashVO queryCashEncashById(String encashId) throws BizException {
		CashEncash cashEncash = cashEncashDao.queryCashEncashById(encashId);
		if(cashEncash != null)
		    cashEncash.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashEncash.getCreateTime()));
		return ObjectOperation.convertByClasses(cashEncash, CashEncashVO.class);
	}

	@Override
	public CashEncashVO queryCashEncashByPid(String partnerId, String pid) throws BizException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("partnerId", partnerId);
		params.put("pid", pid);
		CashEncash cashEncash = cashEncashDao.queryCashEncashByPid(params);
		if(cashEncash != null)
            cashEncash.setCreateTime(FormatOperation.formatYMDHms14ToY_M_DHms(cashEncash.getCreateTime()));
		return ObjectOperation.convertByClasses(cashEncash, CashEncashVO.class);
	}
	
    public List<CashEncashVO> queryAllCashEncash(String accountPeriod, Integer accountStatus, Integer status){
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("accountPeriod", accountPeriod);
        params.put("accountStatus", accountStatus);
        params.put("status", status);
        
        List<CashEncash> list = cashEncashDao.queryAllCashEncash(params);
        return ObjectOperation.convertByClassesList(list, CashEncashVO.class);
    }
	
	@Override
	public List<Map<String, Object>> queryCashEncashAccess(String userId,
                                                           String status, String startDate, String endDate, String accessSQL,
                                                           int pageNum, int numPerPage) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userId);
		map.put("status", status);
		map.put("startDate", startDate);
		map.put("endDate", endDate);
		map.put("accessSQL", accessSQL);
		map.put("pageNum", pageNum);
		map.put("numPerPage", numPerPage);
		
		List<Map<String, Object>> list = cashEncashDao.queryCashEncashAccess(map);
		
		return list;
	}

	@Override
	public int queryCashEncashCountAccess(String userId, String status,
                                          String startDate, String endDate, String accessSQL) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userId", userId);
		map.put("status", status);
		map.put("startDate", startDate);
		map.put("endDate", endDate);
		map.put("accessSQL", accessSQL);
		
		int intNum = cashEncashDao.queryCashEncashCountAccess(map);
		
		return intNum;
	}

	@Override
	public int deleteEncashOrder(String encashId) throws BizException {
		return cashEncashDao.deleteByPrimaryKey(encashId);
	}

	@Override
	public int queryCashEncashByAccountId(String accountId) throws BizException {
		
		return cashEncashDao.queryCashEncashByAccountId(accountId);
	}

	@Override
	public List<CashEncashRecVO> queryCashEncashRec(Integer userType,
													String startTime, String endTime, int pageNum, int numPerPage)
			throws BizException {
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userType", userType);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		map.put("pageNum", pageNum);
		map.put("numPerPage", numPerPage);
		List<CashEncashRec> encashList = cashEncashDao.queryCashEncashRec(map);
		if(encashList != null && encashList.size()>0){
			return ObjectOperation.convertByClassesList(encashList, CashEncashRecVO.class);
		}
		return null;
	}

	@Override
	public int queryCashEncashRecCount(Integer userType, String startTime,
                                       String endTime) throws BizException {

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userType", userType);
		map.put("startTime", startTime);
		map.put("endTime", endTime);
		return cashEncashDao.queryCashEncashRecCount(map);
	}

}
